package com.doit.day07

object _03_模式匹配 {
  def main(args: Array[String]): Unit = {

    val str = "zss"
    //值匹配
    str match {
      case "lss" => println("老王帅")
      case "ww" => println("华哥帅")
      case "zl" => println("宝哥帅")
      case "zss1" => println("匹配成功了")
      case "abc" => println("飞哥就不帅了")
      case _ => println("啥玩意！一个都没我帅！！")
    }

    val num = 50
    val res: String = num match {
      case score:Int if score > 90 => "优秀" + score
      case abc  :Int if abc > 70 => "良好" + abc
      case bcd  :Int if bcd > 60 => "及格" + bcd
      case _ => "不及格" + num
    }
    println(res)

    //匹配类型

    val abc:Any = 19
    abc match {
      case a:String => println("他是一个String 类型")
      case a:Double => println("他是一个Double 类型")
      case a:Float  => println("他是一个Float 类型")
      case a:Int =>  println("他是一个Int 类型")
      case _ => println("啥也不是")
    }


    val array: Array[Any] = Array[Any](1, "str", 1.0, 'c', true, (1, 1.0))
    //如果他是int类型或者是double类型，我就将这个数乘以10返回
    val parFun = new PartialFunction[Any,Double] {
      override def isDefinedAt(x: Any) = x match {
        case a:Int => true
        case a:Double => true
        case _ =>false
      }
      override def apply(v1: Any) = v1 match {
        case a:Int =>    a*10
        case a:Double => a*10
//        case _ => 1
      }
    }
    val doubles: Array[Double] = array.collect(parFun)
    doubles.foreach(println)

    //匹配数组
    val arr  = Array(2,3,4)
    arr match {
      case Array(2,_)=>println("a")
      case Array(1,_,_)=>println("b")
      case Array(_,3,_,_)=>println("c")
      case Array(_,_,_)=>println("d")
      case _ =>println("啥也不是")
    }

    //匹配元祖
    val tuple:Any = (1,"zss",1.9,true)
    tuple match {
      case (a,b) => println("这个代表二元元祖")
      case (a,b,c) => println("这个代表3元元祖")
      case (1,b,_) => println("这个代表3元元祖，第一个元素的值必须是1")
      case (a,"zss",c,d) => println("这个代表四元元祖，并且第二个元素的值必须是zss")
    }

    //解构对象  unapply方法
    //只能应用于实现了apply方法和unapply方法的类
    //case class class和object(伴生类和伴生对象)
    val car: Car = Car("奔驰", 9.9, "黑色")
    car match {
      case Car(brand, price, "黑色") => println(s"匹配上了，品牌是$brand")
      case Car("BMW", 19.9, "白色") => println(s"好像匹配不上")
      case _ => println("啥也不是")
    }

    //定义变量   模式匹配的其他应用场景
    val list = List((1,"zss"),(2,"lss"),(3,"ww"))
    for (elem <- list) {
      println(elem._2)
    }

    for ((_,name) <- list) {
      println(name)
    }


    val (id,name): (Int, String) = (1, "zss")
    //相当于定义了两个变量，id的值是1   name 的值是"zss"
    println(id)
    println(name)

    println("==============================")


    val ints: List[Int] = List(1, 2, 3, 4)
    ints match {
      case lis:List[String] => println("按照道理来说，这个是匹配不上的，因为我上面的ints是List[Int]")
      case lis:List[Int] => println("不好意思，轮不到你")
      case _ => println("最后兜底的")
    }

    //array并不会做泛型的擦除，但是list会
    val ints1: Any = Array(1, 2, 3, 4)
    ints1 match {
      case a:Array[String] => println("按照list而言这个好像可以匹配上")
      case a:Array[Double] => println("a")
      case a:Array[Int] => println("b")
      case _ => println("c")
    }

  }
}


class Car(val brand:String,val price:Double,val color:String)
object Car {
  //属性重组变成一个对象
  def apply(brand: String, price: Double, color: String): Car = new Car(brand, price, color)

  def unapply(arg: Car): Option[(String, Double, String)] = Some(arg.brand, arg.price, arg.color)
}
